// File: main.cpp
//
// Created by 唐建 on 2023/12/1.
//
#include <iostream>
#include <string>
#include <sstream>
#include "json/json.hpp"
#include "simhash/include/Simhasher.hpp"

#include "web/SplitTool.hpp"
#include "web/DistanceTool.hpp"
#include "web/KeyRecommander.h"
#include "web/StdExtension.hpp"
#include "web/ProtocolParser.h"

#define LINEP cout << "-------------------------------------" << endl

using namespace simhash;
using json = nlohmann::json;
using namespace std;

void testJson()
{
    // create a JSON object
    json j =
            {
                    {"pi",      3.141},
                    {"happy",   true},
                    {"name",    "Niels"},
                    {"nothing", nullptr},
                    {
                     "answer",  {
                                        {"everything", 42}
                                }
                    },
                    {"list",    {       1, 0, 2}},
                    {
                     "object",  {
                                        {"currency",   "USD"},
                                           {"value", 42.99}
                                }
                    }
            };

    // add new values
    j["new"]["key"]["value"] = {"another", "list"};

    // count elements
    auto s = j.size();
    j["size"] = s;

    // pretty print with indent of 4 spaces
    std::cout << std::setw(4) << j << '\n';
    ostringstream os;
    os << std::setw(4) << j << '\n';
    std::string a = os.str();
}

int testSimHash()
{
    Simhasher simhasher("../dict/jieba.dict.utf8", "../dict/hmm_model.utf8",
                        "../dict/idf.utf8", "../dict/stop_words.utf8");
    string s("我是蓝翔技工拖拉机学院手扶拖拉机专业的。不用多久，我就会升职加薪，当上总经理，出任CEO，走上人生巅峰。");
    size_t topN = 5;
    uint64_t u64 = 0;
    vector<pair<string, double> > res;
    simhasher.extract(s, res, topN);
    simhasher.make(s, topN, u64);
    cout << "文本：\"" << s << "\"" << endl;
    cout << "关键词序列是: " << res << endl;
    cout << "simhash值是: " << u64 << endl;


    const char *bin1 = "100010110110";
    const char *bin2 = "110001110011";
    uint64_t u1, u2;
    u1 = Simhasher::binaryStringToUint64(bin1);
    u2 = Simhasher::binaryStringToUint64(bin2);

    cout << bin1 << "和" << bin2 << " simhash值的相等判断如下：" << endl;
    cout << "海明距离阈值默认设置为3，则isEqual结果为：" << (Simhasher::isEqual(u1, u2)) << endl;
    cout << "海明距离阈值默认设置为5，则isEqual结果为：" << (Simhasher::isEqual(u1, u2, 5)) << endl;
    return EXIT_SUCCESS;
}

void testSplitToolCppJieba()
{
    // 普通使用
    //SplitToolCppJieba sp;
    //auto v = sp.cut("我是蓝翔技工拖拉机学院手扶拖拉机专业的。不用多久，"
    //                "我就会升职加薪，当上总经理，出任CEO，走上人生巅峰。");
    //cout << v << endl;
    //
    //auto v1 = sp.cut("hello");
    //cout << v1 << endl;
}

void testSplitToolInstant()
{
    // 单例模式
    auto v = SplitToolCppJieba::getInstance()->cut("我是蓝翔技工拖拉机学院手扶拖拉机专业的。不用多久，"
                                                   "我就会升职加薪，当上总经理，出任CEO，走上人生巅峰。");
    cout << v << endl;

    auto v1 = SplitToolCppJieba::getInstance()->cut("hellowordtextbook");
    cout << v1 << endl;
}

void testDistance()
{
    string a = "中国";
    string b = "abcd中国5";

    cout << DistanceTool::editDistance(a, b) << endl;
}

void testCandidateResultPriQue()
{
    std::priority_queue<CandidateResult> a;
    a.emplace("中国", 1, 1);
    a.emplace("中国", 1, 1);
    a.emplace("中国", 1, 1);
    a.emplace("中国", 1, 1);
}

struct Player {
    string name;
    int credits;
    int ranking;
};

NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Player, name, credits, ranking)

#if 0
void to_json(json &j, const Player &p)
{
    j= json{ {"name", p.name},
             {"credits", p.credits},
             {"ranking", p.ranking} };
}
#endif
#if 0
void from_json(const json &j, Player &p)
{
    j.at("name").get_to(p.name);
    j.at("credits").get_to(p.credits);
    j.at("ranking").get_to(p.ranking);
}
#endif

void test()
{
    auto j = R"([
    {"name": "Judd Trump","credits": 1754500,"ranking": 1},
    {"name": "Neil Robertson","credits": 1040500,"ranking": 2},
    {"name": "Ronnie O'Sullivan","credits": 954500,"ranking": 3}
    ])"_json;
    vector<Player> players = j.get<vector<Player>>();
    /* vector<Player> players; */
    /* j.get_to(players); */
    cout << "name:" << players[2].name << endl;
    cout << "credits:" << players[2].credits << endl;
    cout << "ranking:" << players[2].ranking << endl;
}

void test3()
{
    auto j3 = json::parse(R"({"happy": true, "pi": 3.141})");
    cout << "j3 = " << j3 << endl;
    json j_string = "this is a string";
    auto cpp_string = j_string.get<std::string>();
    cout << "cpp_string = " << cpp_string << endl;
}

void test4()
{
    json j_string = "this is a string";
    auto cpp_string = j_string.get<std::string>();
    std::string cpp_string2;
    j_string.get_to(cpp_string2);
    std::string serialized_string = j_string.dump();
    std::cout << cpp_string
              << " == " << cpp_string2
              << " == " << j_string.get<std::string>() << '\n';
    std::cout << j_string
              << " == " << serialized_string << std::endl;
}

void test5()
{
    Player a{"123", 1, 1};
    vector<Player> list = {{"123", 1, 1},
                           {"123", 1, 1},
                           {"123", 1, 1}};
    json j = a;
    cout << std::setw(4) << j << endl;
    cout << j << endl;
    cout << j.dump(4) << endl;
    string str(j.dump(4));
    cout << str << endl;

    json jl = list;
    cout << jl.dump(4) << endl;
}

void testZhStr()
{
    //string text = "今天周五123";
    string text = "今天周五123 hello";
    for (size_t i = 0; i < text.length();) {
        int cplen = 1;
        if ((text[i] & 0xf8) == 0xf0) cplen = 4;     // 占用4个字节，前5位为11110
        else if ((text[i] & 0xf0) == 0xe0) cplen = 3; // 占用3个字节，前4位为1110
        else if ((text[i] & 0xe0) == 0xc0) cplen = 2; // 占用2个字节，前3位为110
        // 个人感觉这行代码好像没什么用，如果三种情况都不符合，那么cplen就为初始化的0，是符合utf-8编码定义的
        if ((i + cplen) > text.length()) cplen = 1;
        cout << text.substr(i, cplen) << endl;
        i += cplen;
    }
}

int main_test_web(int argc, char *argv[])
{
    //testSimHash();
    //testJson();
    //testSplitToolInstant();
    //testDistance();
    //test();
    //testZhStr();

    //LINEP;
    //KeyRecommander kr("hello", nullptr);
    //string result = kr.doQuery();
    //cout << result << endl;
    //LINEP;
    //KeyRecommander kr1("王道", nullptr);
    //string result1 = kr1.doQuery();
    //cout << result1 << endl;
    //LINEP;
    //KeyRecommander kr2("god", nullptr);
    //string result2 = kr2.doQuery();
    //cout << result2 << endl;
    //LINEP;
    //KeyRecommander kr3("王牌", nullptr);
    //string result3 = kr3.doQuery();
    //cout << result3 << endl;
    //LINEP;

    //string msg = "{\"content":”hello”,”mesid\":\"1\",\"pageNum\":2,\"pageSize\":1}";
    //string msg = "{\"content\":\"hello\",\"mesid\":\"1\",\"pageNum\":2,\"pageSize\":1}";
    //nlohmann::json json = nlohmann::json::parse(msg);
    ////std::make_unique<CliRequestMsg>(json.get<CliRequestMsg>());
    //cout << json.dump(4) << endl;
    return 0;
}
